<template>
    <a-dropdown :popPlacement="props.popPlacement" :useTargetWidth="true" :maxHeight="maxHeight" class="a-input-search" v-model:popShown="state.popShown" :trigger="'none'" ref="popupRef">
        <a-control-group>
            <a-input-string class="c-w-100" :color="formItemHook.myColor" :size="formItemHook.mySize" :sharp="formItemHook.mySharp" :disabled="formItemHook.myDisabled" v-model:value="state.displayText" :placeholder="placeholder" :clearable="props.clearable" :isInner="true" @click="state.popShown = true" @clear="methods.input(undefined)"></a-input-string>
            <a-button v-if="attachButtonShown" class="c-f-shrink-0" :color="formItemHook.myColor" :size="formItemHook.mySize" :sharp="formItemHook.mySharp" :disabled="formItemHook.myDisabled" :square="true" ref="btn" @click="methods.search(state.changeId)"><span class="fa fa-fw fa-search"></span></a-button></a-control-group>

        <template v-slot:pop>
            <a-control-group direction="v" :block="true" class="pop" :class="[
                !formItemHook.mySharp ? `c-round-${formItemHook.mySize}` : '',
                ` c-shadow-${formItemHook.mySize}`,
            ]">
                <a-input-check-box-single :color="formItemHook.myColor" :size="formItemHook.mySize" :sharp="formItemHook.mySharp" :disabled="formItemHook.myDisabled || getDisabledFunc(a)" :block="true" :plain="true" v-for="a in state.items" :key="props.getTextFunc(a)" @click="methods.clickItem(a)" :value="value === props.getValueFunc(a)" class="c-f-h c-f-between-center c-f-shrink-0">
                    <template v-slot:prepend>
                        <span>{{ props.getTextFunc(a) }}</span>
                    </template>
                    <template v-slot:checkedFlag>
                        <span class="fa fa-fw fa-check"></span>
                    </template>
                    <template v-slot:unCheckedFlag>
                        <span></span>
                    </template>
                </a-input-check-box-single>
            </a-control-group>
        </template>
    </a-dropdown>
</template>

<style lang="scss" scoped>
@import "../scss/vars";

.pop {
    background-color: $defaultBgColor;
}
</style>

<script setup lang="ts">
import AInputString from './AInputString.vue'
import AControlGroup from './AControlGroup.vue'
import ADropdown from './ADropdown.vue'
import AInputCheckBoxSingle from './AInputCheckBoxSingle.vue'
import AButton from './AButton.vue'
import { InputPropsType, PopPlacementType, PopupExposed, SelectPropsType } from '@/types'
import { reactive, ref, toRef } from 'vue'
import { useInput } from '@/hooks/useInput'
import { useFormItem } from '@/hooks/useFormItem'
import { useSelect } from '@/hooks/useSelect'

interface PropsType extends InputPropsType<any | undefined, never>, SelectPropsType {
    searchFunc?: (displayText?: string) => any[] | Promise<any[]>
    delay?: number
    getTextFunc?: (a: any) => string
    getValueFunc?: (a: any) => any
    getDisplayTextByValueFunc?: (val: any) => string
    popPlacement?: PopPlacementType
    clearable?: boolean
    maxHeight?: number
    placeholder?: string
    attachButtonShown?: boolean
}
const props = withDefaults(defineProps<PropsType>(), {
    value: undefined,
    color: undefined,
    disabled: undefined,
    size: undefined,
    sharp: undefined,
    rules: () => [],
    isInner: false,
    getDisabledFunc: (a: any) => a.disabled,
    searchFunc: (_displayText?: string) => [],
    delay: 0,
    getTextFunc: (a: any) => a.text,
    getValueFunc: (a: any) => a.value,
    getDisplayTextByValueFunc: undefined,
    popPlacement: 'bottom',
    clearable: true,
    maxHeight: undefined,
    placeholder: undefined,
    attachButtonShown: true,
})

interface StateType {
    popShown: boolean
    displayText?: string
    changeId: number
    items: any[]
}
const state = reactive<StateType>({
    popShown: false,
    displayText: undefined,
    changeId: 0,
    items: []
})

const popupRef = ref<PopupExposed>()

const emit = defineEmits<{
    (e: 'update:value', value?: any): void
    (e: 'itemClick', value: any): void
}>()
useInput(props)
const formItemHook = useFormItem(props)
useSelect(props, popupRef, toRef(state.items))

const methods = {
    input(val?: any) {
        emit('update:value', val)
    },
    clickItem(item: any) {
        let displayText = props.getTextFunc(item)
        state.displayText = displayText
        methods.input(props.getValueFunc(item))
        emit('itemClick', item)
        state.popShown = false
    },
    getInputEl() {
        return popupRef.value!.getTargetEl()
    },
    async search(changeId: number) {
        let items = await props.searchFunc(state.displayText)
        if (state.changeId !== changeId) {
            return
        }
        state.items = items
        if (items.length && methods.getInputEl().contains(window.document.activeElement)) {
            state.popShown = true
        }
    }
}
</script>